package priv.mill.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;

public class NonBlockingSocket implements Runnable{

	private static boolean stop;
	private Selector selector;
	private ServerSocketChannel channel;

	public NonBlockingSocket(int port) {
		try {
			selector=Selector.open();
			channel = ServerSocketChannel.open();
			channel.configureBlocking(false);
			channel.socket().bind(new InetSocketAddress(port));
			channel.register(selector, SelectionKey.OP_ACCEPT);
			System.out.printf("服务器开启于%d端口",port);
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	public static void main(String[] args) throws IOException {
		
		int port = 9999;
		
		NonBlockingSocket nonBlockingSocket = new NonBlockingSocket(port);
		new Thread(nonBlockingSocket,"NIO-Socket").start();
	}

	@Override
	public void run() {
		while(!stop) {
			try {
				selector.select(1000);
				Set<SelectionKey> keys = selector.selectedKeys();
				Iterator<SelectionKey> iterator = keys.iterator();	
				while(iterator.hasNext()) {
					SelectionKey key = iterator.next();
					iterator.remove();
					try {
						handlerInput(key);
					}catch (Exception e) {
						if(key!=null)key.cancel();
						if(key.channel()!=null)key.channel().close();
					}
				}
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private void handlerInput(SelectionKey key) throws IOException {
		if(key.isValid()) {
			if(key.isAcceptable()) {
				ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
				SocketChannel sc = ssc.accept();
				sc.configureBlocking(false);
				sc.register(selector, SelectionKey.OP_READ);
				
			}
			if(key.isReadable()) {
				SocketChannel sc = (SocketChannel) key.channel();
				ByteBuffer dst = ByteBuffer.allocate(1024);
				int b = sc.read(dst);
				if(b>0) {
					dst.flip();
					byte[] bytes = new byte[dst.remaining()];
					dst.get(bytes);
					String string = new String(bytes,"UTF-8");
					System.out.println(string);
					doWrite(sc,new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
				}else if(b<0) {
					key.cancel();
					sc.close();
				}
			}
		}
	}

	private void doWrite(SocketChannel sc, String resp) throws IOException {
		if(resp!=null && resp.trim().length()>0) {
			byte[] bytes = resp.getBytes();
			ByteBuffer writeByte = ByteBuffer.allocate(bytes.length);
			writeByte.put(bytes);
			writeByte.flip();
			sc.write(writeByte);
		}
	}

}
